﻿#if !(NETFX_CORE || WINDOWS_PHONE)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;


namespace WindowsCommonStorage
{
    internal class NetFxStorageFolder:CommonStorageFolder
    {

        internal NetFxStorageFolder()
        {
            this._folder = null;
        }


        protected internal override async Task<IEnumerable<CommonStorageFile>> ProtectedGetFilesAsync()
        {
            return await Task.Factory.StartNew((sender) =>
            {
                List<CommonStorageFile> files = new List<CommonStorageFile>();
                foreach (var file in this.EnvironmentFolder.GetFiles())
                {
                    files.Add(new NetFxStorageFile { _file = file });
                }
                return files;

            }, SynchronizationContext.Current).ConfigureAwait(false);
        }

        protected internal override async Task<CommonStorageFolder> ProtectedGetFolderAsync(string name)
        {
            return await Task.Factory.StartNew((sender) =>
            {
                var dirs = this.EnvironmentFolder.GetDirectories(name);
                if (dirs.Length == 0) return null;
                return new NetFxStorageFolder { _folder = dirs.First() };
            }, SynchronizationContext.Current).ConfigureAwait(false);
        }

        protected internal override async Task<IEnumerable<CommonStorageFolder>> ProtectedGetFoldersAsync()
        {
            return await Task.Factory.StartNew((sender) =>
            {
                List<CommonStorageFolder> rslts = new List<CommonStorageFolder>();
                foreach (var folder in this.EnvironmentFolder.GetDirectories())
                {
                    rslts.Add(new NetFxStorageFolder { _folder = folder });
                }
                return rslts;
            }, SynchronizationContext.Current).ConfigureAwait(false);
        }

        protected internal override async Task<CommonStorageFolder> ProtectedCreateFolderAsync(string desiredName)
        {
            return await ProtectedCreateFolderAsync(desiredName, CommonCreationCollisionOption.FailIfExists).ConfigureAwait(false);
            
        }

        protected internal override async Task<CommonStorageFolder> ProtectedCreateFolderAsync(string desiredName, CommonCreationCollisionOption option)
        {
            string path = this.EnvironmentFolder.FullName + "\\" + desiredName;
            if (Directory.Exists(path))
            {
                switch (option)
                {
                    case CommonCreationCollisionOption.FailIfExists:

                        throw new IOException("フォルダがすでに存在します。");


                    case CommonCreationCollisionOption.GenerateUniqueName:

                        path = FileNameExtentions.GetUniqueName(path, 1);

                        break;

                    case CommonCreationCollisionOption.OpenIfExists:

                        return new NetFxStorageFolder { _folder = new DirectoryInfo(path) };

                    case CommonCreationCollisionOption.ReplaceExisting:
                        Directory.Delete(path, true);
                        break;
                }
            }


            return await Task.Factory.StartNew((sender) =>
            {
                return new NetFxStorageFolder { _folder = Directory.CreateDirectory(path) };
            }, SynchronizationContext.Current).ConfigureAwait(false);
            
        }

        

        protected internal override async Task<CommonStorageFile> ProtectedCreateFileAsync(string desiredName)
        {
            return await ProtectedCreateFileAsync(desiredName, CommonCreationCollisionOption.FailIfExists).ConfigureAwait(false);
        }

        protected internal override async Task<CommonStorageFile> ProtectedCreateFileAsync(string desiredName, CommonCreationCollisionOption option)
        {
           
            string path = this.EnvironmentFolder.FullName + "\\" + desiredName;
            if (File.Exists(path))
            {
                switch (option)
                {
                    case CommonCreationCollisionOption.FailIfExists:
                        throw new IOException("すでにファイルは存在します");

                    case CommonCreationCollisionOption.GenerateUniqueName:
                        path = FileNameExtentions.GetUniqueName(path, 1);
                        break;

                    case CommonCreationCollisionOption.ReplaceExisting:
                        File.Delete(path);
                        break;

                    case CommonCreationCollisionOption.OpenIfExists:
                        return new NetFxStorageFile { _file = new FileInfo(path) };
                }

            }

            return await Task.Factory.StartNew((sender) =>
            {
                using (File.Create(path)) { }
                return new NetFxStorageFile { _file = new FileInfo(path) };
            }, SynchronizationContext.Current).ConfigureAwait(false);
  
        }

        protected internal override string ProtectedPath
        {
            get { return this.EnvironmentFolder.FullName; }
        }

        protected internal override string ProtectedName
        {
            get { return this.EnvironmentFolder.Name; }
        }

        protected internal override CommonFileAttributes ProtectedAttributes
        {
            get 
            {
                return CommonFileAttributesExchanger.Exchange(this.EnvironmentFolder.Attributes);
            }
        }

        protected internal override DateTimeOffset ProtectedDateCreated
        {
            get { return this.EnvironmentFolder.CreationTime; }
        }

        protected internal override async Task ProtectedRenameAsync(string desiredName)
        {

            await ProtectedRenameAsync(desiredName, CommonNameCollisionOption.FailIfExists).ConfigureAwait(false);
           
        }

        protected internal override async Task ProtectedRenameAsync(string desiredName, CommonNameCollisionOption option)
        {
            string path = this.EnvironmentFolder.Parent.FullName + "\\" + desiredName;

            if (Directory.Exists(path))
            {

                switch (option)
                {
                    case CommonNameCollisionOption.FailIfExists:
                        throw new IOException("すでにフォルダが存在します");

                    case CommonNameCollisionOption.GenerateUniqueName:
                        path = FileNameExtentions.GetUniqueName(path, 1);
                        break;

                    case CommonNameCollisionOption.ReplaceExisting:
                        Directory.Delete(path, true);
                        break;

                }
            }

            await Task.Factory.StartNew((sender) =>
            {
                this.EnvironmentFolder.MoveTo(path);
            }, SynchronizationContext.Current).ConfigureAwait(false);
        }

        protected internal override async Task ProtectedDeleteAsync()
        {
            await Task.Factory.StartNew((sender) =>
            {
                this.EnvironmentFolder.Delete();
            }, SynchronizationContext.Current).ConfigureAwait(false);
        }



        protected internal override bool ProtectedIsOfType(CommonStorageItemTypes itemType)
        {
            return itemType == CommonStorageItemTypes.Folder;
        }


        protected internal override DirectoryInfo ProtectedEnvironmentFolder
        {
            get { return this._folder; }
        }

        internal DirectoryInfo _folder;

        protected internal static  async Task<CommonStorageFolder> ProtectedGetFolderFromPathAsync(string path)
        {
            return await Task.Factory.StartNew(() =>
            {
                return new NetFxStorageFolder() { _folder = new DirectoryInfo(path) };
            }).ConfigureAwait(false);
        }
    }
}

#endif